package Mapa;

import Objetos.Item;
import Objetos.Objeto;
import Personajes.Enemigo;
import Personajes.Mario;
import Personajes.Personaje;
import TDA_Lista.Position;

public class Manejo_Colisiones {
	protected Mapa_Logico mapa;
	
	public Manejo_Colisiones(Mapa_Logico m){
		mapa = m;
	}
	
	//PARA VERIFICAR COLISIONES ENTRE PERSONAJES Y OBJETOS
	
	/**Retorna true en el caso de que el personaje encuentre 
	 * un obstaculo a la izquierda, falso en caso contrario. */
	public boolean colisionAIzquierda(Personaje p){
		boolean toReturn = false;
		for(Objeto o : mapa.obtenerObjetos()){
			if(o.obtenerX() + p.getRG().getAncho() == p.obtenerX()){
				if((o.obtenerY() - p.obtenerY() < p.getRG().getAlto())&&(o.obtenerY() - p.obtenerY() >= 0)) toReturn = true;
				else if((p.obtenerY() - o.obtenerY() < p.getRG().getAlto())&&(p.obtenerY() - o.obtenerY() >= 0))	toReturn = true;
			}
			if(toReturn) break;
		}
		return toReturn;
	}
	
	/**Retorna true en el caso de que el personaje encuentre 
	 * un obstaculo a la derecha, falso en caso contrario. */
	public boolean colisionADerecha(Personaje p){
		boolean toReturn = false;
		for(Objeto o : mapa.obtenerObjetos()){
			if(o.obtenerX() == p.obtenerX() + p.getRG().getAncho()){
				if((o.obtenerY() - p.obtenerY() < p.getRG().getAlto())&&(o.obtenerY() - p.obtenerY() >= 0)) toReturn = true;
				else if((p.obtenerY() - o.obtenerY() < p.getRG().getAlto())&&(p.obtenerY() - o.obtenerY() >= 0))	toReturn = true;
			}
			if(toReturn) break;
		}
		return toReturn;
	}
	
	/**Retorna true en el caso de que el personaje encuentre un
	 * obstaculo arriba de el, falso en caso contrario. */
	public boolean colisionArriba(Personaje p){
		boolean hayObstaculo = false;
		for(Objeto o : mapa.obtenerObjetos()){
			boolean A1 = p.obtenerX() - o.obtenerX() < p.getRG().getAncho();
			boolean A2 = p.obtenerX() - o.obtenerX() >= 0;
			boolean B1 = o.obtenerX() - p.obtenerX() < p.getRG().getAncho();
			boolean B2 = o.obtenerX() - p.obtenerX() >= 0;
			if((A1 && A2)||(B1 && B2)){
				boolean C = o.obtenerY() + o.getRG().getAlto()  == p.obtenerY();
				if(C){
					if(o.getItem() != null){
						Item i = o.getItem();
						i.aparecio();
						i.setPosicion(o.obtenerX(),o.obtenerY() - 32);
						mapa.obtenerItems().addFirst((Item)i.clonar());
						o.recibirGolpe(mapa.obtenerMario());
					}
					hayObstaculo = true;
					break;
				}
			}
		}
		return hayObstaculo;
	}
	
	/**Retorna true en el caso de que el personaje encuentre un
	 * obstaculo abajo de el, falso en caso contrario. */
	public boolean colisionAbajo(Personaje p){
		boolean hayObstaculo = false;
		for(Objeto o : mapa.obtenerObjetos()){
			boolean A1 = p.obtenerX() - o.obtenerX() < p.getRG().getAncho();
			boolean A2 = p.obtenerX() - o.obtenerX() >= 0;
			boolean B1 = o.obtenerX() - p.obtenerX() < p.getRG().getAncho();
			boolean B2 = o.obtenerX() - p.obtenerX() >= 0;
			if((A1 && A2)||(B1 && B2)){
				boolean C = o.obtenerY() == p.obtenerY() + p.getRG().getAlto();
				if(C){
					hayObstaculo = true;
					break;
				}
			}
		}
		return hayObstaculo;
	}
		
	//COLISION ENTRE PERSONAJES
	public Enemigo colisionLateralMyE(){
		Enemigo toReturn = null;
		Mario mario = mapa.obtenerMario();
		if(!mario.esEstrella() && !mario.esInvencible()){
			for(Enemigo e : mapa.obtenerEnemigos()){
				if((e.obtenerX() == mario.obtenerX() + mario.getRG().getAncho())||(e.obtenerX() + mario.getRG().getAncho() == mario.obtenerX())){
					if((e.obtenerY() - mario.obtenerY() < mario.getRG().getAlto())&&(e.obtenerY() - mario.obtenerY() >= 0)) toReturn = e;
					else if((mario.obtenerY() - e.obtenerY() < mario.getRG().getAlto())&&(mario.obtenerY() - e.obtenerY() >= 0))	toReturn = e;
				}
				if(toReturn != null) break;
			}
		}
		return toReturn;
	}
	
	public Enemigo colisionArribaMyE(){
		Enemigo toReturn = null;
		Mario mario = mapa.obtenerMario();
		if(!mario.esEstrella()){
			for(Enemigo e : mapa.obtenerEnemigos()){
				boolean A1 = mario.obtenerX() - e.obtenerX() < mario.getRG().getAncho();
				boolean A2 = mario.obtenerX() - e.obtenerX() >= 0;
				boolean B1 = e.obtenerX() - mario.obtenerX() < mario.getRG().getAncho();
				boolean B2 = e.obtenerX() - mario.obtenerX() >= 0;
				if((A1 && A2)||(B1 && B2)){
					boolean C = e.obtenerY() + e.getRG().getAlto()  == mario.obtenerY();
					if(C) {
						toReturn = e;
						break;
					}
				}	
			}
		}
		return toReturn;
	}
	
	/**Si el mario pisa un personaje. */
	public void colisionAbajoMyE(){
		Mario mario = mapa.obtenerMario();
		if(!mario.esInvencible()){
			for(Position<Enemigo> e : mapa.obtenerEnemigos().positions()){
				boolean A1 = mario.obtenerX() -  e.element().obtenerX() < mario.getRG().getAncho();
				boolean A2 = mario.obtenerX() -  e.element().obtenerX() >= 0;
				boolean B1 = e.element().obtenerX() - mario.obtenerX() < mario.getRG().getAncho();
				boolean B2 =  e.element().obtenerX() - mario.obtenerX() >= 0;
				if((A1 && A2)||(B1 && B2)){
					boolean C =  e.element().obtenerY() == mario.obtenerY() + mario.getRG().getAlto();
					if(C){
						e.element().recibirGolpe();
						if(e.element().murio()){
							mario.setPuntaje(e.element().getPuntaje());
							if(e.element() != null) mapa.removerEnemigo(e);	
						}
						int i = 0;
						while(i < 128){
							mario.setPosicion(mario.obtenerX(),mario.obtenerY() - 8);
							i += 8;
							try {
								Thread.sleep(20);
							} catch (InterruptedException e1) {
								
							}
						}
						
						break;
					}
				}
			}
		}
	}
		
	//COLISION ITEMS Y OBJETOS
	public boolean colisionAIzquierda(Item i){
		boolean toReturn = false;
		for(Objeto o : mapa.obtenerObjetos()){
			if(o.obtenerX() + i.getRG().getAncho() == i.obtenerX()){
				if((o.obtenerY() - i.obtenerY() < i.getRG().getAlto())&&(o.obtenerY() - i.obtenerY() >= 0)) toReturn = true;
				else if((i.obtenerY() - o.obtenerY() <= i.getRG().getAlto())&&(i.obtenerY() - o.obtenerY() >= 0))	toReturn = true;
			}
			if(toReturn) break;
		}
		return toReturn;
	}
	
	/**Retorna true en el caso de que el personaje encuentre 
	 * un obstaculo a la derecha, falso en caso contrario. */
	public boolean colisionADerecha(Item i){
		boolean toReturn = false;
		for(Objeto o : mapa.obtenerObjetos()){
			if(o.obtenerX() == i.obtenerX() + i.getRG().getAncho()){
				if((o.obtenerY() - i.obtenerY() < i.getRG().getAlto())&&(o.obtenerY() - i.obtenerY() >= 0)) toReturn = true;
				else if((i.obtenerY() - o.obtenerY() <= i.getRG().getAlto())&&(i.obtenerY() - o.obtenerY() >= 0))	toReturn = true;
			}
			if(toReturn) break;
		}
		return toReturn;
	}
	
	/**Retorna true en el caso de que el personaje encuentre un
	 * obstaculo arriba de el, falso en caso contrario. */
	public boolean colisionArriba(Item i){
		boolean hayObstaculo = false;
		for(Objeto o : mapa.obtenerObjetos()){
			boolean A1 = i.obtenerX() - o.obtenerX() < i.getRG().getAncho();
			boolean A2 = i.obtenerX() - o.obtenerX() >= 0;
			boolean B1 = o.obtenerX() - i.obtenerX() < i.getRG().getAncho();
			boolean B2 = o.obtenerX() - i.obtenerX() >= 0;
			if((A1 && A2)||(B1 && B2)){
				boolean C = o.obtenerY() + o.getRG().getAlto()  == i.obtenerY();
				if(C){
					hayObstaculo = true;
					break;
				}
			}
		}
		return hayObstaculo;
	}
	
	/**Retorna true en el caso de que el personaje encuentre un
	 * obstaculo abajo de el, falso en caso contrario. */
	public boolean colisionAbajo(Item i){
		boolean hayObstaculo = false;
		for(Objeto o : mapa.obtenerObjetos()){
			boolean A1 = i.obtenerX() - o.obtenerX() <= i.getRG().getAncho();
			boolean A2 = i.obtenerX() - o.obtenerX() >= 0;
			boolean B1 = o.obtenerX() - i.obtenerX() <= i.getRG().getAncho();
			boolean B2 = o.obtenerX() - i.obtenerX() >= 0;
			if((A1 && A2)||(B1 && B2)){
				boolean C = o.obtenerY() == i.obtenerY() + i.getRG().getAlto();
				if(C){
					hayObstaculo = true;
					break;
				}
			}
		}
		return hayObstaculo;
	}
	
	//COLISION ENTRE LOS ITEMS Y MARIO
	public boolean colisionMyI(Item i){
		boolean toReturn = false;
		Mario mario = mapa.obtenerMario();
		if(((i.obtenerX() - mario.obtenerX() < mario.getRG().getAncho())&&(i.obtenerX() - mario.obtenerX() >= 0))
			||((mario.obtenerX() - i.obtenerX() < mario.getRG().getAncho())&&(mario.obtenerX() - i.obtenerX() >= 0))){
					if((i.obtenerY() - mario.obtenerY() < mario.getRG().getAlto())&&(i.obtenerY() - mario.obtenerY() >= 0)) toReturn = true;
					else if((mario.obtenerY() - i.obtenerY() < mario.getRG().getAlto())&&(mario.obtenerY() - i.obtenerY() >= 0))	toReturn = true;
		}
		if(toReturn) i.recibirGolpe(mario);
		return toReturn;
	}
	
	//COLISION ENTRE ITEMS Y ENEMIGOS
	public boolean colisionIyE(Item i){
		boolean toReturn = false;
		Mario mario = mapa.obtenerMario();
		for(Position<Enemigo> e : mapa.obtenerEnemigos().positions()){
			if(((i.obtenerX() - e.element().obtenerX() < i.getRG().getAncho())&&(i.obtenerX() - e.element().obtenerX() >= 0))
			||((e.element().obtenerX() - i.obtenerX() < i.getRG().getAncho())&&(e.element().obtenerX() - i.obtenerX() >= 0))){
				if((i.obtenerY() - e.element().obtenerY() <= i.getRG().getAlto())&&(i.obtenerY() - e.element().obtenerY() >= 0)) toReturn = true;
				else if((e.element().obtenerY() - i.obtenerY() <= i.getRG().getAlto())&&(e.element().obtenerY() - i.obtenerY() >= 0))	toReturn = true;
			}
			if(toReturn){
				i.golpearEnemigo(e.element());
				if(e.element().murio()){
					mario.setPuntaje(e.element().getPuntaje());
					mapa.removerEnemigo(e);	
				}
				break;
			}
		}
		return toReturn;
	}
}
